package com.ubxtech.web.condition;

import cn.hutool.core.util.StrUtil;
import com.ubxtech.core.context.ContextConstants;
import org.springframework.web.servlet.mvc.condition.RequestCondition;

import jakarta.servlet.http.HttpServletRequest;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Victor.Xiao
 * @since 2023-11-15 20:20
 **/
public class ApiVersionCondition implements RequestCondition<ApiVersionCondition> {
    /**
     * 版本号正则表达式
    */
    private final static Pattern VERSION_PATTERN = Pattern.compile("v(\\d+)");
    /**
     * 版本号
    */
    private int apiVersion;

    public ApiVersionCondition(int apiVersion) {
        this.apiVersion = apiVersion;
    }
    @Override
    public ApiVersionCondition combine(ApiVersionCondition other) {
        // 采取最新版本的约束
        return new ApiVersionCondition(Math.max(this.apiVersion, other.apiVersion));
    }

    @Override
    public ApiVersionCondition getMatchingCondition(HttpServletRequest request) {
        //优先匹配path
        ApiVersionCondition condition = matcherCondition(request.getRequestURI());
        if (condition != null) {
            return condition;
        }
        //再匹配header
        String headerStr = request.getHeader(ContextConstants.API_VERSION_NAME);
        if (StrUtil.isNotBlank(headerStr)) {
            return matcherCondition(headerStr);
        }

        //再匹配参数
        String paramStr = request.getParameter(ContextConstants.API_VERSION_NAME);
        if (StrUtil.isNotBlank(paramStr)) {
            return matcherCondition(paramStr);
        }

        return null;
    }

    private ApiVersionCondition matcherCondition(String source) {
        Matcher matcher = VERSION_PATTERN.matcher(source);
        if (matcher.find()) {
            int version = Integer.parseInt(matcher.group(1));
            // 当前版本大于等于请求的版本，则进行匹配
            if (version >= this.apiVersion) {
                return this;
            }
        }
        return null;
    }

    @Override
    public int compareTo(ApiVersionCondition other, HttpServletRequest request) {
        // 根据具体情况返回比较结果
        return other.apiVersion - this.apiVersion;
    }
}
